<?php
#+------------------------------------------------------------------
#| 普通的。
#+------------------------------------------------------------------
#| Author:Janmas Cromwell <janmas-cromwell@outlook.com>
#+------------------------------------------------------------------
namespace form;

use Exception;
use form\element\form\Button;
use form\element\form\Column;

/**
 * @property Column[] $fields
 */
class Form extends Html
{

	/**
	 * 基本样式
	 */
	const NORMAL = 'normal';
	/**
	 * 表单组
	 */
	const GROUP = 'group';
	/**
	 * 网格式
	 */
	const GRID = 'grid';
	/**
	 * 表格式
	 */
	const TABLE = 'table';
	/**
	 * 垂直
	 */
	const VERTICAL = 'vertical';
	/**
	 * 内联
	 */
	const INLINE = 'inline';

	public $style = '';

	public $id;

	protected $fields = [];

	public function __construct(string $style = 'normal', string $id = '')
	{
		$this->style = $style;
		$this->id = $id;
	}

	public function begin(
		string $action = '',
		string $method = 'get',
		?bool  $novalidate = null,
		string $enctype = 'application/x-www-form-urlencoded',
		?int   $target = null
	)
	{
		$class = 'form-horizontal';
		$validate = '';
		if ($novalidate) {
			$class .= ' needs-validation';
			$validate = ' novalidate';
		}
		if (self::INLINE == $this->style) {
			$class .= ' form-inline';
		}
		$html = "<form class='$class' action='$action' method='$method' ";
		if (!empty($this->id)) {
			$html .= ' id="' . $this->id . '"';
		}

		if (is_numeric($enctype) && !isset($this->enctypeList[$enctype])) {
			throw new Exception(sprintf('不支持的enctype属性%s', $enctype));
		} else if (!in_array($enctype, $this->enctypeList)) {
			throw new Exception(sprintf('不支持的enctype属性%s', $enctype));
		} else {
			$enctype = !is_numeric($enctype) ? $enctype : $this->enctypeList[$enctype];
			$html .= " enctype='$enctype' ";
		}

		if (!is_null($target) && isset($this->targetList[$target])) {
			$target = $this->targetList[$target];
			$this->html .= " target='$target' ";
		}

		$this->html .= $validate;

		$html .= ' >';
		$this->html = $html . PHP_EOL;
		return true;
	}

	public function field($name, string $type = 'input'): Column
	{
		if (array_key_exists($name, $this->fields)) {
			throw new Exception('该name属性的元素已存在');
		}
		$field = Column::create($name, $type, $this->style);
		$this->fields[$name] = $field;
		return $field;
	}

	public function buttons(string $text, string $type = 'submit')
	{
		$field = (new Button())->type($type)->text($text);
		$this->fields[] = $field;
		return $field;
	}

	public function end()
	{
		$this->generate();
		$this->html .= '</form>';
		return parent::display();
	}

	protected function generate(): void
	{
		$hasFile = false;
		while (count($this->fields)) {
			$field = array_shift($this->fields);
			$hasFile = $hasFile ? true : $field->isFile();
			$this->html .= $field->generate();
			$this->registerJs($field->getJs());
			$this->registerCss($field->getCss());
			$this->loadJs($field->getLoadJs());
			$this->loadCss($field->getLoadCss());
		}

		if ($hasFile) {
			$this->html = preg_replace("/enctype='.*'/", 'enctype="multipart/form-data"', $this->html);
		}
	}

	public function display()
	{
		$this->generate();
		$this->html .= '</form>';
		return parent::display(); // TODO: Change the autogenerated stub
	}
}
